package org.travel.app.service.impl;

import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.travel.app.common.util.InitOrder;
import org.travel.app.entity.Order;
import org.travel.app.entity.spots.Spots;
import org.travel.app.entity.spots.SpotsReservation;
import org.travel.app.entity.ticket.TicketStock;
import org.travel.app.mapper.ReservationMapper;
import org.travel.app.mapper.SpotsMapper;
import org.travel.app.service.SpotsService;

import java.math.BigDecimal;
import java.util.List;
import java.util.Random;


/**
 * @author nmm
 * @date 2024-12-2024/12/10
 * @deriction 景点业务接口
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRED)
public class SpotsServiceImpl implements SpotsService {
    private final SpotsMapper spotsMapper;
    private final ReservationMapper reservationMapper;
    private final OrderServiceImpl orderService;
    private final InitOrder initOrder;
    private final TicketServiceImpl ticketService;

    @Override
    public void saveSpots(Spots spots) {
        randomNum(spots);
        spotsMapper.saveSpots(spots);
    }

    /**
     * 随机生成数值
     */
    public void randomNum(Spots spots) {
        Random random=new Random();
        float randomFloat = 4.5f + random.nextFloat() * (10.0f-4.5f);
        // 保留一位小数
        float score = (float) (Math.round(randomFloat * 10) / 10.0);
        int  numReviews= random.nextInt(1500, 5000);
        spots.setScore(new BigDecimal(score));
        spots.setNumReviews(numReviews);
    }

    @Transactional(readOnly = true)
    @Override
    public PageInfo<Spots> getSpotsList(int pageNum, int pageSize, Spots spots) {
        List<Spots> spotsList = spotsMapper.getSpotsList(pageNum, pageSize, spots);
        return new PageInfo<>(spotsList);
    }


    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public String addSpotsReservation(SpotsReservation spotsReservation) {
        setUnUseProperty(spotsReservation);
        reservationMapper.addSpotsReservation(spotsReservation);
        //添加景点预约信息
        if (spotsReservation.getSpotsTicketPackage().getIsPackage()) {
            reduceSpotsTicketPackage(spotsReservation);
            //套餐减库存
        } else {
            //单个票减库存
            ticketService.reduceStock(spotsReservation.getStockId());
        }
        //减库存

        String orderId = saveOrder(spotsReservation);
        return orderId;
        //保存订单
    }

    /**
     * 判断是否是不同票种的套餐
     */
    private void reduceSpotsTicketPackage(SpotsReservation spotsReservation) {
        Integer spotsPackageChoice = ticketService.getSpotsPackageChoice(spotsReservation.getSpotsTicketPackage().getPackageId());
        if (spotsPackageChoice==2){
            packageStockReduce(spotsReservation);
            //减同票种套餐库存
        }else {
             ticketService.getSpotsPackageTicketTypeId(spotsReservation.getSpotsTicketPackage().getPackageId());
            //减不同票种套餐库存
        }
    }


    /**
     * 保存订单信息
     * @param spotsReservation
     */
    public String saveOrder(SpotsReservation spotsReservation) {
        Order order = initOrder.createOrder(spotsReservation);
        //初始化订单信息
        orderService.saveOrder(order);

        //生成景点订单
        saveCouponDetail(spotsReservation,order.getOrderId());
        return order.getOrderId();
    }


    /**
     * 保存优惠信息
     * @param spotsReservation
     */
    public void saveCouponDetail(SpotsReservation spotsReservation,String orderId) {
        //如果优惠信息不为空
        if (spotsReservation.getCouponDetail()!=null){

            spotsReservation.getCouponDetail().setOrderId(orderId);
            //绑定优惠的订单
            orderService.addOrderCoupon(spotsReservation.getCouponDetail());
        }
        //添加订单优惠信息(如果couponDetail不为空)
    }

    /**
     * 套餐减库存
     *
     * @param spotsReservation
     */
    public void packageStockReduce(SpotsReservation spotsReservation) {
        spotsReservation.setSpotId(null);
        spotsReservation.setStockId(null);
        spotsReservation.setSpotsTicketId(null);
        //设置无关属性为空
        int packageId = spotsReservation.getSpotsTicketPackage().getPackageId();
        TicketStock ticketStock = ticketService.countPackageTicket(packageId);
        ticketService.reducePackageStock(ticketStock.getTicketTypesId(), ticketStock.getStock());
        //通过套餐id统计套餐的票数,并通过票种类型进行减数
    }

    /**
     * 将无用字段设置为空
     */
    public void setUnUseProperty(SpotsReservation spotsReservation) {
        if (spotsReservation.getSpotsTicketPackage().getPackageId() == 0) {
            spotsReservation.getSpotsTicketPackage().setPackageId(null);
        }
        if (spotsReservation.getSpotId() == 0) {
            spotsReservation.setSpotId(null);
        }
        if (spotsReservation.getStockId() == 0) {
            spotsReservation.setStockId(null);
        }
        if (spotsReservation.getSpotsTicketId() == 0) {
            spotsReservation.setSpotsTicketId(null);
        }
    }

    @Override
    public Spots getSpotById(Integer spotsId) {
        return spotsMapper.getSpotById(spotsId);
    }

}